<?php
declare(strict_types=1);

namespace App\Controller\Admin\V1\Material;

use App\Controller\Admin\AdminController;
use App\Model\MaterialAssign;
use App\Model\MaterialFlow;
use App\Model\MaterialProjectSheet;
use App\Model\MaterialSheetAssign;
use App\Repositories\AreaRepository;
use App\Repositories\CommunityRepository;
use App\Repositories\MaterialAssignRepository;
use App\Repositories\MaterialFlowRepository;
use App\Repositories\MaterialProjectRepository;
use App\Repositories\MaterialProjectSheetRepository;
use App\Repositories\MaterialRepository;
use App\Repositories\MaterialSheetAssignRepository;
use App\Repositories\StreetRepository;
use App\Request\StoreMaterialRequest;
use Hyperf\DbConnection\Db;

class MaterialController extends AdminController
{
    public function list(){
        $name = $this->request->input('title',null);
        $rows = $this->request->input('rows',10);
        $search=[];
        if($name){
            $search['name']=[
                'field' => 'title',
                'value' => $name,
                'method' => 'like'
            ];
        }
        $orderBy= [
            [
                'field' => 'id',
                'sort' => 'desc'
            ]
        ];
        $datas = MaterialRepository::getInstance()->getList('*',$search,['limit'=>$rows],$orderBy);
        return $this->response->success($datas);
    }

    public function detail(){
        $id = $this->request->input('id');
        $material = MaterialRepository::getInstance()->getById($id);
        return $this->response->success($material);
    }

    public function delete(){
        $id = $this->request->input('id');
        $count_assign = MaterialAssignRepository::getInstance()->count('id',[[
            'field' => 'material_id',
            'value' => $id
        ]]);
        if($count_assign){
            return $this->response->error(10012,'该清单已分配单位');
        }
        DB::beginTransaction();
        try{
            $result = MaterialRepository::getInstance()->delete($id);
            if(!$result){
                throw new \Exception('删除失败');
            }
            //清空分配记录
            if($count_assign){
                $res = MaterialAssignRepository::getInstance()->deleteAll([[
                    'field' => 'material_id',
                    'value' => $id
                ]]);
                if(!$res){
                    throw new \Exception('分配信息删除失败');
                }
            }
            $count_sheet_assign = MaterialSheetAssignRepository::getInstance()->count('id',[[
                'field' => 'material_id',
                'value' => $id
            ]]);
            if($count_sheet_assign){
                $res = MaterialSheetAssignRepository::getInstance()->deleteAll([[
                    'field' => 'material_id',
                    'value' => $id
                ]]);
                if(!$res){
                    throw new \Exception('分配信息删除失败');
                }
            }
            $count_flow = MaterialFlowRepository::getInstance()->count('id',[[
                'field' => 'material_id',
                'value' => $id
            ]]);
            if($count_flow){
                $res = MaterialFlowRepository::getInstance()->deleteAll([[
                    'field' => 'material_id',
                    'value' => $id
                ]]);
                if(!$res){
                    throw new \Exception('流程信息删除失败');
                }
            }
            DB::commit();
        }catch(\Exception $e){
            DB::rollBack();
            return $this->response->error(10012,$e->getMessage());
        }
        return $this->response->success([]);
    }
    public function store(StoreMaterialRequest $request){
        $admin = $this->request->getAttribute('admin');
        $params = $request->all();
        $params['admin_id'] = $admin->id;
        DB::beginTransaction();
        try{
            $result = MaterialRepository::getInstance()->store($params);
            if(!$result['success']){
                throw new \Exception('材料清单保存失败');
            }
            $material = $result['data'];
            DB::commit();
        }catch(\Throwable $e){
            DB::rollBack();
            return $this->response->error(10012,$e->getMessage());
        }
        return $this->response->success([
            'id' => $material->id
        ]);
    }

    public function assignDetail(){
        $material_id = $this->request->input('material_id',0);
        $result = MaterialAssign::query()->where('material_id',$material_id)->select(['type'])->distinct()->get();
        return $this->response->success([
            'types' => $result?$result->pluck('type')->toArray():[],
        ]);
    }

    public function assignDetailbak(){
        $material_id = $this->request->input('material_id',0);
        $result = MaterialSheetAssign::query()->where('material_id',$material_id)->select(['data_id','type'])->distinct()->get();
        $district = collect($result)->filter(function($item){
            return $item->type == MaterialAssign::TYPE_ONE;
        });
        $street = collect($result)->filter(function($item){
            return $item->type == MaterialAssign::TYPE_TWO;
        });
        $community = collect($result)->filter(function($item){
            return $item->type == MaterialAssign::TYPE_THREE;
        });
        return $this->response->success([
            'district' => $district->pluck('data_id')->toArray(),
            'street' => $street->pluck('data_id')->toArray(),
            'community' => $community->pluck('data_id')->toArray()
        ]);
    }

    public function assign(){
        $select_types = $this->request->input('types','');
        $select_types = explode(',',$select_types);
        $material_id = $this->request->input('material_id',0);
        $types = MaterialSheetAssign::getLabels('type');
        $sheets = MaterialProjectSheet::query()->where('material_id',$material_id)->select(['id','project_id'])
            ->orderBy('listorder','asc')
            ->get();
        $count_assign = MaterialAssign::query()->where('material_id',$material_id)->count('id');
        if($count_assign){
            return $this->response->error(10020,'清单已分配单位,请先撤回在分配');
        }
        DB::beginTransaction();
        try{
            foreach ($types as $type=>$lable){
                if(in_array($type,$select_types)){
                    $count = MaterialAssign::query()->where('material_id',$material_id)->where('type',$type)->count('id');
                    if($count){
                        continue;
                    }
                    $datas=null;
                    switch ($type){
                        case MaterialAssign::TYPE_ONE:
                            $datas = AreaRepository::getInstance()->all(['id','name'],[[
                                'field' => 'parent_id',
                                'value' => '223'
                            ]],[[
                                'field' => 'listorder',
                                'sort' => 'asc'
                            ]]);
                            break;
                        case MaterialAssign::TYPE_TWO:
                            $datas = StreetRepository::getInstance()->all(['id','name'],[],[[
                                'field' => 'id',
                                'sort' => 'asc'
                            ]]);
                            break;
                        case MaterialAssign::TYPE_THREE:
                            $datas = CommunityRepository::getInstance()->all(['id','name'],[],[[
                                'field' => 'id',
                                'sort' => 'asc'
                            ]]);
                            break;
                    }
                    if($datas){
                        co(function() use($datas,$material_id,$sheets,$type){
                            foreach ($datas as $item){
                                $assign_m = new MaterialAssign();
                                $assign_m->material_id = $material_id;
                                $assign_m->data_id = $item->id;
                                $assign_m->type = $type;
                                if(!$assign_m->save()){
                                    throw new \Exception('保存失败');
                                }
                                foreach ($sheets as $sheet){
                                    $_tag = new MaterialSheetAssign();
                                    $_tag->material_id = $material_id;
                                    $_tag->project_id = $sheet->project_id;
                                    $_tag->sheet_id = $sheet->id;
                                    $_tag->data_id = $item->id;
                                    $_tag->type = $type;
                                    if(!$_tag->save()){
                                        throw new \Exception('保存失败');
                                    }
                                }
                            }

                        });
                    }
                }else{
                    $count_m = MaterialAssign::query()->where('material_id',$material_id)->where('type',$type)->count('id');
                    $count_m_sheet = MaterialSheetAssign::query()->where('material_id',$material_id)->where('type',$type)->count('id');
                    if($count_m){
                        if(!MaterialAssign::query()->where('material_id',$material_id)->where('type',$type)->delete()){
                            throw new \Exception('清除数据失败');
                        }
                    }
                    if($count_m_sheet){
                        if(!MaterialSheetAssign::query()->where('material_id',$material_id)->where('type',$type)->delete()){
                            throw new \Exception('清除数据失败');
                        }
                    }
                }
            }
            DB::commit();
        }catch (\Throwable $e){
            DB::rollBack();
            return $this->response->error(10040,$e->getMessage());
        }
        return $this->response->success([
        ]);
    }

    public function assignbak2(){
        $districts = $this->request->input('district');
        $streets = $this->request->input('street');
        $communities = $this->request->input('community');
        $district_ids = json_decode($districts,true);
        $street_ids = json_decode($streets,true);
        $community_ids = json_decode($communities,true);
        $material_id = $this->request->input('material_id',0);
        $types = MaterialSheetAssign::getLabels('type');
        $ids[MaterialSheetAssign::TYPE_ONE] = $district_ids;
        $ids[MaterialSheetAssign::TYPE_TWO] = $street_ids;
        $ids[MaterialSheetAssign::TYPE_THREE] = $community_ids;
        $sheets = MaterialProjectSheet::query()->where('material_id',$material_id)->select(['id','project_id'])
            ->orderBy('listorder','asc')
            ->get();
        DB::beginTransaction();
        try{
            foreach ($types as $type=>$lable){
                /**
                 * material分发
                 */
                $select_m_tags = MaterialAssign::query()->where('material_id',$material_id)
                    ->where('type',$type)
                    ->get()
                    ->pluck('data_id')
                    ->toArray();
                $delete_m_tags = array_merge(array_diff($select_m_tags,$ids[$type]));
                $add_m_tags = array_merge(array_diff($ids[$type],$select_m_tags));
                if(!empty($delete_m_tags)){
                    MaterialAssign::query()->where('material_id',$material_id)
                        ->whereIn('data_id',$delete_m_tags)
                        ->delete();
                }
                if(!empty($add_m_tags)){
                    foreach ($add_m_tags as $tag){
                        if($tag=='') continue;
                        $_tag = new MaterialAssign();
                        $_tag->material_id = $material_id;
                        $_tag->data_id = $tag;
                        $_tag->type = $type;
                        if(!$_tag->save()){
                            throw new \Exception('保存失败');
                        }
                    }
                }
                /**
                 * sheet分发
                 */
                $select_tags = MaterialSheetAssign::query()->distinct('data_id')->where('material_id',$material_id)
                    ->where('type',$type)
                    ->get()
                    ->pluck('data_id')
                    ->toArray();
                $delete_tags = array_merge(array_diff($select_tags,$ids[$type]));
                $add_tags = array_merge(array_diff($ids[$type],$select_tags));
                if(!empty($delete_tags)){
                    MaterialSheetAssign::query()->where('material_id',$material_id)
                        ->whereIn('data_id',$delete_tags)
                        ->delete();
                }
                if(!empty($add_tags)){
                    foreach ($add_tags as $tag){
                        if($tag=='') continue;
                        co(function() use($tag,$material_id,$sheets,$type){
                            foreach ($sheets as $sheet){
                                $_tag = new MaterialSheetAssign();
                                $_tag->material_id = $material_id;
                                $_tag->project_id = $sheet->project_id;
                                $_tag->sheet_id = $sheet->id;
                                $_tag->data_id = $tag;
                                $_tag->type = $type;
                                if(!$_tag->save()){
                                    throw new \Exception('保存失败');
                                }
                            }
                        });
                    }
                }
            }
            DB::commit();
        }catch (\Throwable $e){
            DB::rollBack();
            return $this->response->error(10040,$e->getMessage());
        }
        return $this->response->success([
        ]);
    }

    public function recall(){
        $material_id = $this->request->input('id',0);
        DB::beginTransaction();
        try{
            $count = MaterialSheetAssignRepository::getInstance()->count('id',[[
                'field' => 'material_id',
                'value' => $material_id
            ]]);
            if($count){
                $result = MaterialSheetAssignRepository::getInstance()->deleteAll([[
                    'field' => 'material_id',
                    'value' => $material_id
                ]]);
                if(!$result){
                    throw new \Exception('内容分配删除失败');
                }
            }
            $count_assign = MaterialAssignRepository::getInstance()->count('id',[[
                'field' => 'material_id',
                'value' => $material_id
            ]]);
            if($count_assign){
                $res = MaterialAssignRepository::getInstance()->deleteAll([[
                    'field' => 'material_id',
                    'value' => $material_id
                ]]);
                if(!$res){
                    throw new \Exception('分配信息删除失败');
                }
            }
            $count_flow = MaterialFlowRepository::getInstance()->count('id',[[
                'field' => 'material_id',
                'value' => $material_id
            ]]);
            if($count_flow){
                $res = MaterialFlowRepository::getInstance()->deleteAll([[
                    'field' => 'material_id',
                    'value' => $material_id
                ]]);
                if(!$res){
                    throw new \Exception('流程信息删除失败');
                }
            }
            DB::commit();
        }catch(\Exception $e){
            DB::rollBack();
            return $this->response->error(10012,$e->getMessage());
        }

        return $this->response->success([]);
    }

    public function assignbak(){
        $districts = $this->request->input('district');
        $streets = $this->request->input('street');
        $communities = $this->request->input('community');
        $district_ids = json_decode($districts,true);
        $street_ids = json_decode($streets,true);
        $community_ids = json_decode($communities,true);
        $material_id = $this->request->input('material_id',0);
        $types = MaterialAssign::getLabels('type');
        $ids[MaterialAssign::TYPE_ONE] = $district_ids;
        $ids[MaterialAssign::TYPE_TWO] = $street_ids;
        $ids[MaterialAssign::TYPE_THREE] = $community_ids;
        DB::beginTransaction();
        try{
            foreach ($types as $type=>$lable){
                $select_tags = MaterialAssign::query()->where('material_id',$material_id)
                    ->where('type',$type)
                    ->get()
                    ->pluck('data_id')
                    ->toArray();
                $delete_tags = array_merge(array_diff($select_tags,$ids[$type]));
                $add_tags = array_merge(array_diff($ids[$type],$select_tags));
                if(!empty($delete_tags)){
                    MaterialAssign::query()->where('material_id',$material_id)
                        ->whereIn('data_id',$delete_tags)
                        ->delete();
                }
                if(!empty($add_tags)){
                    foreach ($add_tags as $tag){
                        if($tag=='') continue;
                        $_tag = new MaterialAssign();
                        $_tag->material_id = $material_id;
                        $_tag->data_id = $tag;
                        $_tag->type = $type;
                        if(!$_tag->save()){
                            throw new \Exception('保存失败');
                        }
                    }
                }
            }
            DB::commit();
        }catch (\Throwable $e){
            DB::rollBack();
            return $this->response->error(10040,$e->getMessage());
        }
        return $this->response->success([
        ]);
    }

    public function show(){
        $id = $this->request->input('id');
        $material = MaterialRepository::getInstance()->getById($id);
        $projects = MaterialProjectRepository::getInstance()->all('*',[[
            'field' => 'material_id',
            'value' => $id
        ]],[[
            'field' => 'listorder',
            'sort' => 'asc'
        ]]);
        return $this->response->success([
            'material' => $material,
            'projects' => $projects
        ]);
    }

}